<template>
  <div class="gps-calculator-container">
    <h2 class="title">GPS Distance Calculator</h2>
    <div class="columns-container">
      <div class="column left-column">
        <el-form label-width="auto" class="form-no-wrap">
          <el-form-item label="Latitude 1 (DMS)">
            <el-input v-model="lat1DMS" placeholder="e.g., 52 13 35" @change="convertDMS('lat1DMS', 'lat1Decimal')"></el-input>
          </el-form-item>
          <el-form-item label="Latitude 1 (Decimal)">
            <el-input v-model="lat1Decimal" disabled></el-input>
          </el-form-item>
          <el-form-item label="Longitude 1 (DMS)">
            <el-input v-model="lng1DMS" placeholder="e.g., 21 0 44" @change="convertDMS('lng1DMS', 'lng1Decimal')"></el-input>
          </el-form-item>
          <el-form-item label="Longitude 1 (Decimal)">
            <el-input v-model="lng1Decimal" disabled></el-input>
          </el-form-item>
          <el-form-item label="Latitude 2 (DMS)">
            <el-input v-model="lat2DMS" placeholder="e.g., 52 24 23" @change="convertDMS('lat2DMS', 'lat2Decimal')"></el-input>
          </el-form-item>
          <el-form-item label="Latitude 2 (Decimal)">
            <el-input v-model="lat2Decimal" disabled></el-input>
          </el-form-item>
          <el-form-item label="Longitude 2 (DMS)">
            <el-input v-model="lng2DMS" placeholder="e.g., 16 55 30" @change="convertDMS('lng2DMS', 'lng2Decimal')"></el-input>
          </el-form-item>
          <el-form-item label="Longitude 2 (Decimal)">
            <el-input v-model="lng2Decimal" disabled></el-input>
          </el-form-item>
          <el-form-item label="Precision">
            <el-row :gutter="10">
              <el-col :span="11">
                <el-form-item label="Minute Precision" label-width="auto">
                  <el-input-number v-model="minutesPrecision" :min="0" :max="10" placeholder="e.g., 2" @change="validateInt('minutesPrecision')"></el-input-number>
                </el-form-item>
              </el-col>
              <el-col :span="11">
                <el-form-item label="Second Precision" label-width="auto">
                  <el-input-number v-model="secondsPrecision" :min="0" :max="10" placeholder="e.g., 3" @change="validateInt('secondsPrecision')"></el-input-number>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item class="centered-button">
            <el-row type="flex" justify="center">
              <el-button type="primary" @click="calculateDistance">Calculate Distance</el-button>
            </el-row>
          </el-form-item>
          <el-form-item v-if="distance !== null" class="centered-result">
            <el-row type="flex" justify="center">
              <el-alert :title="`Distance: ${distance.toFixed(2)} cm (${(distance / 100).toFixed(2)} m)`" type="info" show-icon closable @close="clearDistance" class="custom-alert"></el-alert>
            </el-row>
          </el-form-item>
        </el-form>
      </div>
      <div class="column right-column">
        <el-form label-width="auto" class="form-no-wrap">
          <el-form-item label="Latitude 1 (Decimal)">
            <el-input v-model="lat1DecimalDirect" placeholder="e.g., 52.2296756" @change="validateDecimal('lat1DecimalDirect')"></el-input>
          </el-form-item>
          <el-form-item label="Longitude 1 (Decimal)">
            <el-input v-model="lng1DecimalDirect" placeholder="e.g., 21.0122287" @change="validateDecimal('lng1DecimalDirect')"></el-input>
          </el-form-item>
          <el-form-item label="Latitude 2 (Decimal)">
            <el-input v-model="lat2DecimalDirect" placeholder="e.g., 52.406374" @change="validateDecimal('lat2DecimalDirect')"></el-input>
          </el-form-item>
          <el-form-item label="Longitude 2 (Decimal)">
            <el-input v-model="lng2DecimalDirect" placeholder="e.g., 16.9251681" @change="validateDecimal('lng2DecimalDirect')"></el-input>
          </el-form-item>
          <el-form-item class="centered-button">
            <el-row type="flex" justify="center">
              <el-button type="primary" @click="calculateDistanceDirect">Calculate Distance</el-button>
            </el-row>
          </el-form-item>
          <el-form-item v-if="distanceDirect !== null" class="centered-result">
            <el-row type="flex" justify="center">
              <el-alert :title="`Distance: ${distanceDirect.toFixed(2)} cm (${(distanceDirect / 100).toFixed(2)} m)`" type="info" show-icon closable @close="clearDistanceDirect" class="custom-alert"></el-alert>
            </el-row>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      lat1DMS: '',
      lng1DMS: '',
      lat2DMS: '',
      lng2DMS: '',
      lat1Decimal: '',
      lng1Decimal: '',
      lat2Decimal: '',
      lng2Decimal: '',
      lat1DecimalDirect: '',
      lng1DecimalDirect: '',
      lat2DecimalDirect: '',
      lng2DecimalDirect: '',
      distance: null,
      distanceDirect: null,
      secondsPrecision: 3, // 秒的默认精度为3
      minutesPrecision: 2, // 分的默认精度为2
    };
  },
  methods: {
    // 验证DMS格式
    validateDMS(key) {
      const regex = new RegExp(`^\\d{1,3} \\d{1,2}(\\.\\d{1,${this.minutesPrecision}})? \\d{1,2}(\\.\\d{1,${this.secondsPrecision}})?$`);
      if (!regex.test(this[key])) {
        this.$message.error(`${key} must be in DMS format with precision up to ${this.minutesPrecision} decimal places for minutes and ${this.secondsPrecision} decimal places for seconds (e.g., 52 13.12 35.123)`);
        this[key] = '';
      }
    },
    // 验证十进制度格式
    validateDecimal(key) {
      const regex = /^-?\d+(\.\d+)?$/;
      if (!regex.test(this[key])) {
        this.$message.error(`${key} must be a valid decimal number (e.g., 52.2296756)`);
        this[key] = '';
      }
    },
    // 验证整数
    validateInt(key) {
      const value = this[key];
      if (!Number.isInteger(value)) {
        this.$message.error(`${key} must be an integer`);
        this[key] = Math.floor(value);
      }
    },
    // DMS转十进制度
    dmsToDecimal(dms) {
      const parts = dms.split(' ').map(Number);
      if (parts.length === 3) {
        const [d, m, s] = parts;
        return d + (m / 60) + (s / 3600);
      }
      return 0;
    },
    // 十进制度转DMS
    decimalToDMS(decimal) {
      const d = Math.floor(decimal);
      const m = ((decimal - d) * 60).toFixed(this.minutesPrecision);
      const s = (((decimal - d) * 60 - m) * 60).toFixed(this.secondsPrecision);
      return `${d} ${m} ${s}`;
    },
    // 转换DMS到十进制度并显示
    convertDMS(dmsKey, decimalKey) {
      this.validateDMS(dmsKey);
      this[decimalKey] = this.dmsToDecimal(this[dmsKey]).toFixed(7); // 固定保留7位小数
    },
    // 计算两点间的距离（基于DMS）
    calculateDistance() {
      const R = 6371000; // 地球半径，单位为米
      const lat1 = parseFloat(this.lat1Decimal);
      const lng1 = parseFloat(this.lng1Decimal);
      const lat2 = parseFloat(this.lat2Decimal);
      const lng2 = parseFloat(this.lng2Decimal);

      const φ1 = lat1 * Math.PI / 180; // φ, λ in radians
      const φ2 = lat2 * Math.PI / 180;
      const Δφ = (lat2 - lat1) * Math.PI / 180;
      const Δλ = (lng2 - lng1) * Math.PI / 180;

      const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
          Math.cos(φ1) * Math.cos(φ2) *
          Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

      this.distance = R * c * 100; // 距离转换为厘米
    },
    // 计算两点间的距离（基于十进制度）
    calculateDistanceDirect() {
      const R = 6371000; // 地球半径，单位为米
      const lat1 = parseFloat(this.lat1DecimalDirect);
      const lng1 = parseFloat(this.lng1DecimalDirect);
      const lat2 = parseFloat(this.lat2DecimalDirect);
      const lng2 = parseFloat(this.lng2DecimalDirect);

      const φ1 = lat1 * Math.PI / 180; // φ, λ in radians
      const φ2 = lat2 * Math.PI / 180;
      const Δφ = (lat2 - lat1) * Math.PI / 180;
      const Δλ = (lng2 - lng1) * Math.PI / 180;

      const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
          Math.cos(φ1) * Math.cos(φ2) *
          Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

      this.distanceDirect = R * c * 100; // 距离转换为厘米
    },
    // 清除DMS计算结果
    clearDistance() {
      this.distance = null;
    },
    // 清除十进制度计算结果
    clearDistanceDirect() {
      this.distanceDirect = null;
    }
  }
};
</script>

<style scoped>
/* 容器样式 */
.gps-calculator-container {
  padding: 20px;
  background-color: #f9f9f9;
  border: 1px solid #dcdcdc;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  margin: 0 20px;
}

/* 标题样式 */
.title {
  text-align: center;
  color: #333;
  font-size: 24px;
  margin-bottom: 20px;
  font-weight: bold;
  text-transform: uppercase;
}

/* 列容器样式 */
.columns-container {
  display: flex;
  gap: 10px; /* 设置两栏之间的间距为10px */
}

/* 左栏样式 */
.column {
  flex: 1;
  padding: 10px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.left-column {
  border-right: 1px solid #dcdcdc;
}

.right-column {
  border-left: 1px solid #dcdcdc;
}

/* 表单样式 */
.form-no-wrap .el-form-item__label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.centered-button .el-row {
  margin: 0 auto;
}

.centered-result .el-row {
  margin: 0 auto;
  width: fit-content;
}

/* 自定义 el-alert 样式 */
.custom-alert {
  padding: 12px 48px 12px 16px; /* 增加右边的内边距 */
  position: relative;
  display: flex;
  align-items: center; /* 垂直居中对齐 */
  justify-content: space-between; /* 内容和关闭按钮之间留出空间 */
}

.custom-alert .el-alert__content {
  flex: 1; /* 确保内容占据剩余空间 */
}

.custom-alert .el-alert__closebtn {
  position: absolute;
  top: 50%;
  right: 16px; /* 调整关闭按钮的位置 */
  transform: translateY(-50%); /* 垂直居中对齐 */
}
</style>